package com.flute.framework;

import java.util.ArrayList;
import java.util.List;

import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;

import com.flute.framework.index.IDocumentBuilder;
import com.flute.framework.index.analysis.PayloadTokenizer;
import com.flute.framework.index.fieldbuilder.IFieldBuilder;
import com.flute.framework.index.fieldbuilder.ISorterScorer;
import com.flute.framework.index.fieldbuilder.SameFieldBuilder;
import com.flute.framework.index.fieldbuilder.ScoreField;
import com.flute.framework.search.ISearcher;
import com.flute.tools.data.DataRecord;
import com.flute.tools.util.StringUtil;

public class LuceneDocumentBuilder implements IDocumentBuilder {
	private List<IFieldBuilder> fieldBuilderList;
	private List<ISorterScorer> sorters;

	public LuceneDocumentBuilder() {
		this.fieldBuilderList = new ArrayList<IFieldBuilder>();
		this.sorters = new ArrayList<ISorterScorer>();
	}

	public List<ISorterScorer> getSorters() {
		return sorters;
	}

	public void setSorters(List<ISorterScorer> sorters) {
		this.sorters = sorters;
	}

	public void addFieldBuilder(IFieldBuilder fieldBuilder) {
		this.fieldBuilderList.add(fieldBuilder);
	}

	public void addSorter(ISorterScorer sorter) {
		this.sorters.add(sorter);
	}

	@Override
	public Object buildDocument(DataRecord record) {
		Document doc = new Document();

		// 计算活动，分为两种情况,isTop和Activity
		// 对于isTop，field值为true或者false，采用当前字符串作为关键字，在块内得分为ISearcher.SCORE_FACTOR
		// - 100
		// 对于activity，以给定的字符串作为关键字，如果有给定的排序，则得分为ISearcher.SCORE_FACTOR -
		// pos，如果没有则为ISearcher.SCORE_FACTOR - 100
		String activity = record.getFieldValue(ACTIVITY_FIELD);
		boolean istop = false;
		String[] activityWords = null;
		int activityPosition = -1;
		if (!StringUtil.isNullOrEmpty(activity)) {
			try {
				istop = Boolean.valueOf(activity);
			} catch (Exception e) {
			}

			if (!istop) {
				String[] ss = activity.split(ACTIVITY_SPLITER);
				if (ss.length > 0) {
					try {
						activityPosition = Integer.valueOf(ss[ss.length - 1]);
						if (ss.length > 1) {
							activityWords = new String[ss.length - 1];
						}
						for (int i = 0; i < ss.length - 1; i++) {
							activityWords[i] = ss[i];
						}
					} catch (Exception e) {
						activityWords = new String[ss.length];
						for (int i = 0; i < ss.length; i++) {
							activityWords[i] = ss[i];
						}
						activityPosition = 100;
					}
				}
			}
		}

		// 活动为activity,则只有'default'一个排序方式,具体分数按照上诉介绍.
		if (!istop && activityWords != null && activityWords.length > 0
				&& activityPosition > -1) {
			ScoreField sf = new ScoreField();
			for (String s : activityWords) {
				s = StringUtil.getStandardString(s);
				sf.addString(s);
				sf.addScore(s, ScoreField.DEFAULT_SCORE, ISearcher.SCORE_FACTOR
						- activityPosition * ISearcher.SCORE_FACTOR / 1000);
			}
			PayloadTokenizer tk = new PayloadTokenizer(sf);
			doc.add(new Field(ACTIVITY_FIELD, tk));
		}

		for (IFieldBuilder builder : fieldBuilderList) {
			Field field = (Field) builder.buildField(record);
			// Score field
			if (field.tokenStreamValue() != null) {
				PayloadTokenizer pt = (PayloadTokenizer) field
						.tokenStreamValue();
				ScoreField sf = pt.getScoreField();
				if (istop) {
					// 活动为isTop,则只有'default'一个排序方式,具体分数按照上诉介绍.
					for (String s : sf.getStrings()) {
						sf.updateScore(s, ScoreField.DEFAULT_SCORE,
								ISearcher.SCORE_FACTOR - 100f);
					}
				} else {
					// 计算正常record
					for (String s : sf.getStrings()) {
						if (sorters != null) {
							for (ISorterScorer ss : sorters) {
								sf.addScore(s, ss.score(record));
							}
						}
					}
				}
			}

			doc.add(field);
		}

		// Add ID
		SameFieldBuilder builder = new SameFieldBuilder();
		builder.setDataField(DOCUMENT_ID);
		builder.setDocField(DOCUMENT_ID);
		doc.add((Field) builder.buildField(record));

		return doc;
	}

	public List<IFieldBuilder> getFieldBuilderList() {
		return fieldBuilderList;
	}

	public void setFieldBuilderList(List<IFieldBuilder> fieldBuilderList) {
		this.fieldBuilderList = fieldBuilderList;
	}
}
